package com.qzboot.basic.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.qzboot.basic.service.mapper.SysMenuMapper;
import com.qzboot.common.constant.SysConst;
import com.qzboot.facade.entity.SysMenu;
import com.qzboot.facade.service.SysMenuService;
import com.qzboot.facade.service.SysRoleMenuService;
import com.qzboot.facade.support.CrudServiceImpl;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.List;

/**
 * @author zengzhihong
 */
@Service
public class SysMenuServiceImpl extends CrudServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Autowired
    private SysRoleMenuService sysRoleMenuService;

    @Override
    public List<String> listPermsByUserId(Long userId) {
        return baseMapper.listPermsByUserId(userId);
    }

    @Override
    public List<SysMenu> listByUserId(Long userId, Long parentId) {
        if (SysConst.ADMIN_USER_ID.equals(userId)) {
            return baseMapper.selectList(
                    Wrappers.<SysMenu>lambdaQuery().eq(ObjectUtil.isNotNull(parentId), SysMenu::getParentId, parentId)
                            .ne(SysMenu::getMenuType, SysConst.MenuType.BUTTON.getValue())
                            .orderByAsc(SysMenu::getSortNum));
        }
        return baseMapper.listByUserId(userId, parentId);
    }

    @Override
    public List<Long> listMenuIdByRoleId(Long roleId) {
        return baseMapper.listMenuIdByRoleId(roleId);
    }


    @Override
    public SysMenu save(SysMenu entity) {
        //校验参数
        checkMenu(entity);
        baseMapper.insert(entity);
        return entity;
    }

    @Override
    public boolean updateById(SysMenu entity) {
        //校验参数
        checkMenu(entity);
        //菜单类型不能被修改
        entity.setMenuType(null);
        return SqlHelper.retBool(baseMapper.updateById(entity));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeById(Serializable id) {
        //查询是否存在子级
        List<SysMenu> existMenuList = baseMapper.selectList(Wrappers.<SysMenu>lambdaQuery().select(SysMenu::getId).eq(SysMenu::getParentId, id));
        Assert.isTrue(CollectionUtil.isEmpty(existMenuList), "存在子级,不能删除");
        //删除角色菜单
        sysRoleMenuService.removeByMenuIdList(CollectionUtil.newArrayList((Long) id));
        return SqlHelper.retBool(baseMapper.deleteById(id));
    }

    private void checkMenu(SysMenu entity) {
        SysMenu parentMenu = null;
        //目录
        if (entity.getParentId() != 0) {
            parentMenu = baseMapper.selectById(entity.getParentId());
            Assert.notNull(parentMenu, "父级不存在");
        }

        if (SysConst.MenuType.CATALOG.getValue().equals(entity.getMenuType())) {
            if (ObjectUtil.isNotNull(parentMenu)) {
                Assert.isTrue(parentMenu.getMenuType() == 0, "目录类型的上级必须是目录");
            }
        }
        if (SysConst.MenuType.MENU.getValue().equals(entity.getMenuType())) {
            //菜单
            Assert.isTrue(StrUtil.isNotBlank(entity.getPath()), "路径不能为空");
            if (ObjectUtil.isNotNull(parentMenu)) {
                Assert.isTrue(parentMenu.getMenuType() == 0, "菜单类型的上级必须是目录");
            }
        }
        if (SysConst.MenuType.BUTTON.getValue().equals(entity.getMenuType())) {
            //按钮
            Assert.isTrue(StrUtil.isNotBlank(entity.getPerms()), "权限标识不能为空");
            if (ObjectUtil.isNotNull(parentMenu)) {
                Assert.isTrue(parentMenu.getMenuType() == 1, "按钮类型的上级必须是菜单");
            }
        }
        Assert.isTrue(entity.getMenuType() >= 0 && entity.getMenuType() < 3, "按钮类型错误");
    }
}
